package com.guazai.apigateway.utils;

import cn.hutool.core.lang.Snowflake;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.stereotype.Component;

import java.util.Collections;

import static com.guazai.apigateway.constant.RedisConfig.*;

/**
 * @author guazai
 * @date 2025-04-25 18:59:17
 */
@Component
public class SlidingWindow {
    /**
     * 滑动窗口长度
     */
    private Integer windowDuration = WINDOW_DURATION;

    /**
     * 滑动窗口大小
     */
    private Integer maxCount = MAX_COUNT;

    private Snowflake snowflake = new Snowflake();

    private static final DefaultRedisScript<Long> SECKILL_SCRIPT;

    /**
     * 读取seckillVoucher.lua脚本
     */
    static {
        SECKILL_SCRIPT = new DefaultRedisScript<>();
        SECKILL_SCRIPT.setLocation(new ClassPathResource(SLIDING_WINDOW_PATH));
        SECKILL_SCRIPT.setResultType(Long.class);
    }

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    public boolean access(String accessKey) {
        Long max = System.currentTimeMillis();
        Long min = max - windowDuration;
        Long result = stringRedisTemplate.execute(
                SECKILL_SCRIPT,
                Collections.emptyList(),
                min.toString(),
                max.toString(),
                maxCount.toString(),
                accessKey,
                String.valueOf(snowflake.nextId())
        );
        return result == 1;
    }
}
